package com.cetccloud.ap.proxy.channel.cossDomain.s30.channel.send;

import com.cetccloud.ap.config.ProxyConfig;
import com.cetccloud.ap.proxy.channel.cossDomain.s30.S30Config;
import com.cetccloud.ap.proxy.channel.cossDomain.s30.S30Exception;
import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import com.thunisoft.exchange.gateway.protocol.GatewayProtocol;
import com.thunisoft.exchange.gateway.protocol.channel.GatewayChannelMessage;
import com.thunisoft.exchange.gateway.protocol.file.GatewayFileMessage;
import com.wish.xsagent.JXSAgent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @ClassName S30SendChannel
 * @Description
 * @Author superz
 * @Date 2021/4/23 10:34
 * @Version 1.0
 **/
@Slf4j
@Component
public class S30SendChannel {

    @Autowired
    private ProxyConfig proxyConfig;

    @Autowired
    private S30Config s30Config;

    @Autowired
    private Recv4SendHandle recv4SendHandle;

    @Autowired
    private Conn4SendHandle conn4SendHandle;

    private Pointer self;

    public void start() {
        if (proxyConfig.isMock()) {
            log.info("### S30SendChannel start [mock state] ###");
            return;
        }
        log.info("### S30SendChannel start ###, appId: {}, ip: {}, port: {}", s30Config.getProxy().getAppId(), s30Config.getPeer().getSend().getIp(), Short.parseShort(s30Config.getPeer().getSend().getPort()));
        try {
            self = JXSAgent.INSTANCE.initialize(s30Config.getProxy().getAppId(), s30Config.getPeer().getSend().getIp(), Short.parseShort(s30Config.getPeer().getSend().getPort()));
            JXSAgent.INSTANCE.set_log_level(self, 1);
            JXSAgent.INSTANCE.disable_crypto(self);
            JXSAgent.INSTANCE.set_recv_handle(self, recv4SendHandle);
            JXSAgent.INSTANCE.set_conn_handle(self, conn4SendHandle);
            JXSAgent.INSTANCE.start_up(self);
            log.info("### S30SendChannel start ### end");
        } catch (Throwable t) {
            log.error("### S30SendChannel start ### error", t);
        }
    }

    public boolean asyncSend(GatewayChannelMessage channelMessage) throws S30Exception {
        if (!isConnected()) {
            throw new S30Exception("与30s还未成功建立连接");
        }
        try {
            byte[] bytes = GatewayProtocol.encodeChannelMessage(channelMessage);
            return JXSAgent.INSTANCE.async_send(self, bytes, new NativeLong(bytes.length));
        } catch (Exception e) {
            throw new S30Exception(e);
        }
    }

    /**
     * 走目录方式，不走接口
     */
    public boolean asyncSend(GatewayFileMessage fileMessage) throws S30Exception {
        if (!isConnected()) {
            throw new S30Exception("与30s还未成功建立连接");
        }
        try {
            byte[] bytes = GatewayProtocol.encodeFileMessage(fileMessage);
            return JXSAgent.INSTANCE.async_send(self, bytes, new NativeLong(bytes.length));
        } catch (Exception e) {
            throw new S30Exception(e);
        }
    }

    public boolean isConnected() {
        return conn4SendHandle.isConnected();
    }

    public void stop() {
        if (proxyConfig.isMock()) {
            log.info("### S30SendChannel stop [mock state] ###");
            return;
        }
        log.info("### S30SendChannel stop ###");
        JXSAgent.INSTANCE.shut_down(self);
        JXSAgent.INSTANCE.finalize(self);
    }
}
